package com.bite.friend.Service.ServiceImpl;

import Constants.RedisConstant;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bite.friend.Mapper.MessageMapper;
import com.bite.friend.Mapper.MessageTextMapper;
import com.bite.friend.Service.MessageService;
import com.bite.friend.VO.MessageVO;
import com.bite.friend.doamin.Message;
import com.bite.friend.doamin.MessageText;
import domain.MyThreadLocal;
import domain.PageDTO;
import domain.TableDataInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MessageServiceImpl implements MessageService {

    @Autowired
    private StringRedisTemplate redis;

    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    private MessageTextMapper messageTextMapper;
    @Override
    public TableDataInfo list(PageDTO pageDTO) {
        //获取用户id
        String userId = MyThreadLocal.get();
        //先查看redis中是否存在数据
        Long size = redis.opsForList().size(RedisConstant.USER_INFO_LIST_ID + userId);
        if (size == null || size == 0){
            //重新刷新数据
            rashRedisUserInfoList(userId);
        }
        int start = (pageDTO.getPage() - 1) * pageDTO.getPageSize();
        int end = start + pageDTO.getPageSize() - 1;
        //获取用户信息id列表
        List<String> infoIdStrList
                = redis.opsForList().range(RedisConstant.USER_INFO_LIST_ID + userId, start, end);
        if (CollUtil.isEmpty(infoIdStrList)){
            log.info("消息为空，请联系管理员");
            return TableDataInfo.empty();
        }
        //加上前缀
        List<String> infoList = infoIdStrList.stream().map(e -> RedisConstant.USER_INFO_DETAIL + e).toList();

        //获取到信息详情
        List<String> messageList = redis.opsForValue().multiGet(infoList);
        if (CollUtil.isEmpty(messageList) || messageList.size() != infoIdStrList.size()){
            log.info("消息出现问题，请联系管理员");
            return TableDataInfo.empty();
        }
        
        //转换为对象类型
        List<MessageVO> collect = messageList.stream().map(e -> JSONUtil.toBean(e, MessageVO.class)).toList();
        return TableDataInfo.success(collect, infoIdStrList.size());
    }

    private void rashRedisUserInfoList(String userId) {
        //从数据库中，先查询信息
        List<Message> messages = messageMapper.selectList(new LambdaQueryWrapper<Message>()
                .eq(Message::getRecId, userId));
        if (CollUtil.isEmpty(messages)){
            throw new RuntimeException("从数据库中查询到的消息为空，请联系管理员");
        }
        List<Long> textIdList = messages.stream().map(Message::getTextId).toList();
        //根据textId查询信息详情
        List<MessageText> messageTexts = messageTextMapper.selectList(new LambdaQueryWrapper<MessageText>()
                .in(MessageText::getTextId, textIdList));
        if (CollUtil.isEmpty(messageTexts)){
            throw new RuntimeException("从数据库中查询到的消息详情为空，请联系管理员");
        }
        List<MessageVO> messageVOS = BeanUtil.copyToList(messageTexts, MessageVO.class);
        Map<String, String> stringMessageVOMap = new HashMap<>();
        for (MessageVO messageVO : messageVOS) {
            stringMessageVOMap.put(RedisConstant.USER_INFO_DETAIL + messageVO.getTextId(), JSONUtil.toJsonStr(messageVO));
        }
        //最后将数据存放到redis中
        redis.opsForList().rightPushAll(RedisConstant.USER_INFO_LIST_ID + userId, String.valueOf(textIdList));
        redis.opsForValue().multiSet(stringMessageVOMap);
    }
}
